#ifndef _UI_POPUP_H
#define _UI_POPUP_H

#include "script/state_holder.h"
#include "ui/ui_mover.h"
#include "ui/ui_widget.h"
#include "transition.h"

namespace gameflow
{

class	UIPopup
{
public:

	struct	UINavigationElement
	{
		ui::UIWidget*			pWidget;
	};

					UIPopup(const std::string& Panel, const std::string& CloseButton);
	virtual			~UIPopup();
	virtual void	Show(ui::UIMover::MoverEvent Event);
	virtual void	Hide(ui::UIMover::MoverEvent Event);
	virtual void	Render();	
	virtual void	Tick(float dt);
	virtual void	Init();
	virtual void	ForceHide();

	ui::UIWidget*		GetWidget(const std::string& Name);
	void				SetWidgetText(const std::string& Name, const std::string& Text);
	void				SetWidgetFunctor(const std::string& Widget, ui::UIWidget::tdgEvent Event, ui::UIWidget::WIDGET_EVENT EventID = ui::UIWidget::WE_LMB_RELEASE);
	void				SetWidgetPopup(const std::string& WidgetName, const std::string& PopupName, GameTransition::TransitionEvent		OnStart=NULL, ui::UIMover::MoverEvent		OnFinish=NULL);
	void				SetupTransition(const std::string& Widget, const std::string& ToState, const std::string& Sound = "", GameTransition::TransitionEvent	OnFinish=NULL);

// accessors
	const std::string	GetName() const { return m_Name; };
	const std::string	GetPanelName() const { return m_Panel; };
	ui::UIWidget*		GetPanel() { return m_pPanel; };
	float				GetBGAlpha() const { return m_BGAlpha; };
	void				SetBGAlpha(float f) { m_BGAlpha = f; };
	bool				GetPreventClickthroughs() const { return m_PreventClickthroughs; };
	void				SetPreventClickthroughs(bool b) { m_PreventClickthroughs = b; };
	bool				IsActive() { return m_pPanel && m_pPanel->IsVisible(); };

	// setup the nav mesh for Wiimotes
	void				AddNavElement(const std::string& Name) {	if (ui::UIWidget* pWidget = GetWidget(Name)) { m_NavList.push_back(pWidget); } };
	virtual void		DPadNav(int	DirX, int DirY, int	Triggered);
protected:

	void DELEGATE_CALL			OnTransition(GameTransition*);
	void DELEGATE_CALL			OnClosePanel(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	virtual void		OnShowComplete();
	virtual void		OnHideComplete();

	std::string		m_Name;
	std::string		m_Panel;
	ui::UIWidget*	m_pPanel;
	float			m_BGAlpha;
	bool			m_PreventClickthroughs;

	std::vector<ui::UIWidget*>					m_NavList;
	int										m_CurrentIdx;

};

class	UIPopupAnimations : public script::StateHolder
{
public:
	static UIPopupAnimations&		Instance();

	void							ApplyAnimation(ui::UIWidget*	pWidget, const std::string& Name, float Delay = 0.0f, bool HideAfter = true, ui::UIMover::MoverEvent	Event = NULL);
	std::string						GetEndAnim();
	std::string						GetStartAnim();
private:
	std::vector<std::string>		m_StartAnimations;
	std::vector<std::string>		m_EndAnimations;
	UIPopupAnimations();
	~UIPopupAnimations(){};
};

class	UIPopupManager
{
public:
	static UIPopupManager&		Instance();
	/// popup management
	 UIPopup*				AddPopup(const std::string& File, const std::string& CloseButton = "");
	 UIPopup*				AddPopup(UIPopup* pPopup);

	 UIPopup*				StartPopup(const std::string& Name, ui::UIMover::MoverEvent Event = 0);
	 void					EndPopup(const std::string& Name, ui::UIMover::MoverEvent Event = 0);
	 void					HideAllPopups();
	 UIPopup*				GetPopup(const std::string& Name);
	 void					SetWidgetPopup(ui::UIWidget* pWidget, const std::string& PopupName, GameTransition::TransitionEvent		OnStart=NULL, ui::UIMover::MoverEvent		OnFinish=NULL);
	 UIPopup*				GetActivePopup();

/// shortcuts
	 bool					StartYesNo(const std::string& Text, ui::UIWidget::tdgEvent OnYes, ui::UIWidget::tdgEvent OnNo);
	 bool					StartPrompt(const std::string& Heading, const std::string& Text, const std::string& OKText, ui::UIWidget::tdgEvent OnOK);

	virtual void		DPadNav(int	DirX, int DirY, int	Triggered);
private:	
	void DELEGATE_CALL			OnPopupClicked(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);

								UIPopupManager();
								~UIPopupManager();
	struct				UIPopupNotification
	{
		std::string							PopupName;
		ui::UIWidget*						pSourceWidget;	// used to determine which transition to call
		GameTransition::TransitionEvent		OnStart;
		ui::UIMover::MoverEvent				OnFinish;
	};
	std::vector<UIPopupNotification*>		m_PopupNotification;
	std::vector<UIPopup*>					m_Popups;

	struct				YesNoNotification
	{
		YesNoNotification() : pYes(NULL), pNo(NULL), OnYes(NULL), OnNo(NULL) {};
		ui::UIWidget*					pYes;
		ui::UIWidget*					pNo;
		std::string						Text;
		ui::UIWidget::tdgEvent		OnYes;
		ui::UIWidget::tdgEvent		OnNo;
	};
	YesNoNotification						m_YesNoResponse;
	ui::UIWidget::tdgEvent					m_PromptAction;
	void DELEGATE_CALL						OnYesNo(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
	void DELEGATE_CALL						OnPromptOK(ui::UIWidget::WIDGET_EVENT Event, ui::UIWidget* pWidget);
};

} //namespace gameflow
#endif //_UI_POPUP_H
